#define _DEFAULT_SOURCE /* needed for usleep() */
#include <stdlib.h>
#include <unistd.h>
#define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
#include <SDL2/SDL.h>
#include "lvgl/lvgl.h"
#include "lvgl/examples/lv_examples.h"
#include "lvgl/demos/lv_demos.h"
#include "lv_drivers/sdl/sdl.h"
#include "SquareLine_Export/ui.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void hal_init(void);

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *      VARIABLES
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void demo1()
{
    #define COLOR_BLUE     lv_color_hex(0x0000FF)
    #define COLOR_BLACK    lv_color_hex(0x000000)

    //设置对象属性
    //1.构建一个显示图层
    lv_obj_t* screen=lv_scr_act();
    //2.显示一个对象
    lv_obj_t* obj=lv_obj_create(screen);
    //3.设置对象的位置
    lv_obj_set_pos(obj,10,10);
    //4.设置对象的大小
    lv_obj_set_size(obj,100,50);
    //5.设置居中，直接覆盖之前的位置设置
    //lv_obj_center(obj);

    //设置样式
    static lv_style_t style;
    // 初始化样式对象
    lv_style_init(&style);
    // 设置背景颜色
    lv_style_set_bg_color(&style, lv_color_hex(0xD3E4E9));
    // 设置边框颜色
    lv_style_set_border_color(&style, COLOR_BLACK);
    // 设置边框宽度为5像素
    lv_style_set_border_width(&style,2);
    // 设置圆角半径为10像素
    lv_style_set_radius(&style,10);


    // 将样式应用到对象的主部件
    lv_obj_add_style(obj,&style,LV_PART_MAIN);

}

void demo_Chinese()
{
  //声明字体
  LV_FONT_DECLARE(SanJiNeng);
  //1.设置文本标签属性
  // 获取当前活跃的屏幕
  lv_obj_t* screen=lv_scr_act();
  // 创建一个标签对象
  lv_obj_t* label=lv_label_create(screen);
  // 设置标签文本
  lv_label_set_text(label,"中文测试案例");
  lv_obj_set_pos(label,10,10);
  // 设置标签文本颜色
  lv_obj_set_style_text_color(label,lv_color_hex(0xFF0000),LV_PART_MAIN);

  //2.定义样式
  static lv_style_t style;
  lv_style_init(&style);
  lv_style_set_text_font(&style,&SanJiNeng);

  //3.将样式应用到标签对象
  lv_obj_add_style(label,&style,LV_PART_MAIN);
}

void event_handler(lv_event_t * e){
  int code = lv_event_get_code(e);
  lv_obj_t* obj = lv_event_get_target(e);

  if(code == LV_EVENT_CLICKED){
    lv_obj_t* label = lv_event_get_user_data(e);
    lv_label_set_text(label,"Pressed");
    printf("clicked\n");
  }
}

void demo_btn_click()
{
    lv_obj_t* screen=lv_scr_act();
    lv_obj_t* btn=lv_btn_create(screen);
    lv_obj_set_pos(btn,10,10);

    //创建样式
    static lv_style_t style;
    lv_style_init(&style);
    lv_style_set_height(&style,60);
    lv_style_set_width(&style,100);

    lv_style_set_bg_color(&style,lv_color_hex(0xD3E4E9));
    lv_style_set_radius(&style,10);

    //设置按钮文本
    lv_obj_t* label = lv_label_create(btn);
    lv_label_set_text(label,"Button");
    lv_obj_center(label);

    lv_obj_add_style(btn,&style,0);

    //给按钮添加点击事件 需要将 label 作为用户数据传递给事件回调
    lv_obj_add_event_cb(btn,event_handler,LV_EVENT_CLICKED,label);

}

void btn_matrix_callback(lv_event_t* e)
{
  int code = lv_event_get_code(e);
  lv_obj_t* btn_matrix = lv_event_get_target(e);
  if(code == LV_EVENT_VALUE_CHANGED)
  {
    uint16_t selected_index = lv_btnmatrix_get_selected_btn(btn_matrix);
    char* text = lv_btnmatrix_get_btn_text(btn_matrix,selected_index);
    printf("Clicked:%s\n",text);
  }
}

void demo_btn_matrix()
{
    lv_obj_t* screen=lv_scr_act();
    lv_obj_t* btn_matrix=lv_btnmatrix_create(screen);
    
    lv_obj_set_pos(btn_matrix,10,10);

    static const char* map[]={"1","2","3","\n","4","5","6","\n","7","8","9","\n","BACK","0","ENTER",""};
    lv_btnmatrix_set_map(btn_matrix,map);

    lv_obj_set_size(btn_matrix,200,200);

    //矩阵按钮关联事件
    lv_obj_add_event_cb(btn_matrix,btn_matrix_callback,LV_EVENT_ALL,NULL);
}

void btnm_event_handler(lv_event_t* e){
  int code = lv_event_get_code(e);
  lv_obj_t* target = lv_event_get_target(e);
  lv_obj_t* textarea = lv_event_get_user_data(e);
  if(code == LV_EVENT_VALUE_CHANGED){
    // 获取单击的按钮编号
    uint16_t index = lv_btnmatrix_get_selected_btn(target);
    // 获取单击的按钮文本
    const char* btn_text = lv_btnmatrix_get_btn_text(target,index);
    // 条件判断
    if(strcmp(btn_text,LV_SYMBOL_BACKSPACE) == 0){
      lv_textarea_del_char(textarea);
    }else if (strcmp(btn_text,LV_SYMBOL_NEW_LINE) == 0)
    {
      printf("enter clicked\n");
      lv_textarea_add_text(textarea, "\n");
      lv_event_send(textarea, LV_EVENT_READY, NULL);
    }else{
        // 向文本框中填入内
      lv_textarea_add_text(textarea,btn_text);
    }
  }
}
static void textarea_event_handler(lv_event_t * e)
{
    lv_obj_t * ta = lv_event_get_target(e);
    printf("Enter was pressed. The current text is: %s", lv_textarea_get_text(ta));
}
void demo6(){
  // 文本框
  lv_obj_t* textarea = lv_textarea_create(lv_scr_act());
  lv_textarea_set_one_line(textarea,true);
  lv_obj_align(textarea,LV_ALIGN_TOP_MID,0,10);
  lv_obj_set_width(textarea,220);
  lv_obj_add_state(textarea, LV_STATE_FOCUSED);
  lv_obj_add_event_cb(textarea, textarea_event_handler, LV_EVENT_READY, textarea);
  // 创建矩阵按钮
  lv_obj_t* btnm = lv_btnmatrix_create(lv_scr_act());
  // 设置矩阵按钮的显示
 static const char* map[]={"1","2","3","\n","4","5","6","\n","7","8","9","\n",LV_SYMBOL_BACKSPACE,"0",LV_SYMBOL_NEW_LINE,""};

  lv_btnmatrix_set_map(btnm,map);
  lv_obj_set_width(btnm,220);
  lv_obj_align(btnm,LV_ALIGN_TOP_MID,0,80);
  lv_obj_clear_flag(btnm, LV_OBJ_FLAG_CLICK_FOCUSABLE); 
  // 事件处理
  lv_obj_add_event_cb(btnm,btnm_event_handler,LV_EVENT_VALUE_CHANGED,textarea);
}

void demo_show_img()
{
  lv_obj_t* screen=lv_scr_act();
  lv_obj_t* img=lv_img_create(screen);
  //声明图片
  LV_IMG_DECLARE(monkey);
  lv_img_set_src(img,&monkey);
  
  lv_obj_align(img,LV_ALIGN_CENTER,0,0);
}

void demo_show_gif()
{
  lv_obj_t* screen=lv_scr_act();
  lv_obj_t* gif=lv_gif_create(screen);
  //声明图片
  LV_IMG_DECLARE(astronaut);
  lv_gif_set_src(gif,&astronaut);
  
  lv_obj_align(gif,LV_ALIGN_CENTER,0,0);
}


void flex_1(void)
{
    /*Create a container with ROW flex direction*/
    lv_obj_t * cont_row = lv_obj_create(lv_scr_act());
    lv_obj_set_size(cont_row, 240, 75);
    lv_obj_align(cont_row, LV_ALIGN_TOP_MID, 0, 5);
    lv_obj_set_flex_flow(cont_row, LV_FLEX_FLOW_ROW);

    /*Create a container with COLUMN flex direction*/
    lv_obj_t * cont_col = lv_obj_create(lv_scr_act());
    lv_obj_set_size(cont_col, 200, 200);
    lv_obj_align_to(cont_col, cont_row, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);
    lv_obj_set_flex_flow(cont_col, LV_FLEX_FLOW_COLUMN);

    uint32_t i;
    for(i = 0; i < 10; i++) {
        lv_obj_t * obj;
        lv_obj_t * label;

        /*Add items to the row*/
        obj= lv_btn_create(cont_row);
        lv_obj_set_size(obj, 100, LV_PCT(100));

        label = lv_label_create(obj);
        lv_label_set_text_fmt(label, "Item: %u", i);
        lv_obj_center(label);

        /*Add items to the column*/
        obj = lv_btn_create(cont_col);
        lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);

        label = lv_label_create(obj);
        lv_label_set_text_fmt(label, "Item: %"LV_PRIu32, i);
        lv_obj_center(label);
    }
}

lv_obj_t* page1;
lv_obj_t* page2;
void page_event_cb(lv_event_t* event){

  // 如果是page1，切换到page2，否则切换回page1
  lv_obj_t* page = lv_event_get_user_data(event);
  lv_disp_load_scr(page);

  // lv_obj_t* target = lv_event_get_target(event);
  // printf("target: %p \n", target);
  // printf("page1: %p page2: %p\n", page1, page2);

  // if(target == page1){
  //   lv_disp_load_scr(page2);
  // }else if(target == page2){
  //   lv_disp_load_scr(page1);
  // }
}

void create_page1(){

  page1 = lv_obj_create(NULL);

  static lv_style_t style;
  lv_style_init(&style);
  // 设置背景色
  lv_style_set_bg_color(&style, lv_palette_main(LV_PALETTE_PINK));
  lv_obj_add_style(page1, &style, 0);

  // 添加Label
  lv_obj_t* label = lv_label_create(page1);
  lv_label_set_text(label, "Page1");
  lv_obj_set_align(label, LV_ALIGN_CENTER);

}

void create_page2(){

  page2 = lv_obj_create(NULL);

  static lv_style_t style;

  lv_style_init(&style);
  // 设置宽高
  // lv_style_set_width(&style, 100);
  // lv_style_set_height(&style, 100);
  // 设置背景色
  lv_style_set_bg_color(&style, lv_palette_main(LV_PALETTE_CYAN));

  lv_obj_add_style(page2, &style, 0);

  // 添加Label
  lv_obj_t* label = lv_label_create(page2);
  lv_label_set_text(label, "Page2");
  lv_obj_set_align(label, LV_ALIGN_CENTER);

}


int main(int argc, char **argv)
{
  (void)argc; /*Unused*/
  (void)argv; /*Unused*/

  /*Initialize LVGL*/
  lv_init();

  /*Initialize the HAL (display, input devices, tick) for LVGL*/
  hal_init();

  // lv_example_switch_1();
//  lv_example_calendar_1();
//  lv_example_btnmatrix_2();
//  lv_example_checkbox_1();
//  lv_example_colorwheel_1();
//  lv_example_chart_6();
//  lv_example_table_2();
//  lv_example_scroll_2();
//  lv_example_textarea_1();
//  lv_example_msgbox_1();
//  lv_example_dropdown_2();
//  lv_example_btn_1();
//  lv_example_scroll_1();
//  lv_example_tabview_1();
//  lv_example_tabview_1();
//  lv_example_flex_3();
//  lv_example_label_1();

    //  lv_demo_widgets();

    // demo1();
    // demo_Chinese();
    // demo_btn_click();
    // demo_btn_matrix();
    // demo6();
    // demo_show_img();
    // demo_show_gif();
    // flex_1();

    // demo_page-----------------------------------------------------------
    // create_page1();
    // create_page2();
    // lv_obj_add_event_cb(page2, page_event_cb, LV_EVENT_CLICKED, page1);
    // lv_obj_add_event_cb(page1, page_event_cb, LV_EVENT_CLICKED, page2);
    // lv_disp_load_scr(page1);
    ui_init();
  while(1) {
      /* Periodically call the lv_task handler.
       * It could be done in a timer interrupt or an OS task too.*/
      lv_timer_handler();
      usleep(5 * 1000);
  }

  return 0;
}

/**********************
 *   STATIC FUNCTIONS
 **********************/

/**
 * Initialize the Hardware Abstraction Layer (HAL) for the LVGL graphics
 * library
 */
static void hal_init(void)
{
  /* Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/
  sdl_init();

  /*Create a display buffer*/
  static lv_disp_draw_buf_t disp_buf1;
  static lv_color_t buf1_1[SDL_HOR_RES * 100];
  lv_disp_draw_buf_init(&disp_buf1, buf1_1, NULL, SDL_HOR_RES * 100);

  /*Create a display*/
  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv); /*Basic initialization*/
  disp_drv.draw_buf = &disp_buf1;
  disp_drv.flush_cb = sdl_display_flush;
  disp_drv.hor_res = SDL_HOR_RES;
  disp_drv.ver_res = SDL_VER_RES;

  lv_disp_t * disp = lv_disp_drv_register(&disp_drv);

  lv_theme_t * th = lv_theme_default_init(disp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), LV_THEME_DEFAULT_DARK, LV_FONT_DEFAULT);
  lv_disp_set_theme(disp, th);

  lv_group_t * g = lv_group_create();
  lv_group_set_default(g);

  /* Add the mouse as input device
   * Use the 'mouse' driver which reads the PC's mouse*/
  static lv_indev_drv_t indev_drv_1;
  lv_indev_drv_init(&indev_drv_1); /*Basic initialization*/
  indev_drv_1.type = LV_INDEV_TYPE_POINTER;

  /*This function will be called periodically (by the library) to get the mouse position and state*/
  indev_drv_1.read_cb = sdl_mouse_read;
  lv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);

  static lv_indev_drv_t indev_drv_2;
  lv_indev_drv_init(&indev_drv_2); /*Basic initialization*/
  indev_drv_2.type = LV_INDEV_TYPE_KEYPAD;
  indev_drv_2.read_cb = sdl_keyboard_read;
  lv_indev_t *kb_indev = lv_indev_drv_register(&indev_drv_2);
  lv_indev_set_group(kb_indev, g);

  static lv_indev_drv_t indev_drv_3;
  lv_indev_drv_init(&indev_drv_3); /*Basic initialization*/
  indev_drv_3.type = LV_INDEV_TYPE_ENCODER;
  indev_drv_3.read_cb = sdl_mousewheel_read;
  lv_indev_t * enc_indev = lv_indev_drv_register(&indev_drv_3);
  lv_indev_set_group(enc_indev, g);

  /*Set a cursor for the mouse*/
  LV_IMG_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
  lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
  lv_img_set_src(cursor_obj, &mouse_cursor_icon);           /*Set the image source*/
  lv_indev_set_cursor(mouse_indev, cursor_obj);             /*Connect the image  object to the driver*/
}
